#include <Arduino.h>
#include "atom.h"
#include "atomtimer.h"
#include "console.h"
#include "debug.h"
#include "iosdrv.h"
#include "syslog.h"
#include "iap.h"

/* Constants */

/* Local data */

/* Application threads' TCBs */
static ATOM_TCB main_tcb = DEFAULT_TCB("main");

/* Main thread's stack area */
static uint8_t main_thread_stack[ATOM_MAIN_STACK_SIZE_BYTES];

/* Idle thread's stack area */
static uint8_t idle_thread_stack[ATOM_IDLE_STACK_SIZE_BYTES];

/* Forward declarations */
static void main_thread_func (uint32_t data);

static char logo[] = {
"\r\n\
-------------------------------------------------------- \r\n \
 __   __  _______  _______  ___      _______  \r\n \
|  |_|  ||   _   ||       ||   |    |       | \r\n \
|       ||  |_|  ||    _  ||   |    |    ___| \r\n \
|       ||       ||   |_| ||   |    |   |___  \r\n \
|       ||       ||    ___||   |___ |    ___| \r\n \
| ||_|| ||   _   ||   |    |       ||   |___  \r\n \
|_|   |_||__| |__||___|    |_______||_______| \r\n \
                                              \r\n \
                    powered by yifengling0    \r\n \
                    ver " APP_VERSION "  " __DATE__ " " __TIME__ "\r\n \
-------------------------------------------------------- \
 \r\n"
};

extern "C" int board_setup(void);

void setup() 
{
  uint8_t status;
  ConsoleInit();
  IosDrvInit();

  board_setup();

  status = atomOSInit(&idle_thread_stack[0], ATOM_IDLE_STACK_SIZE_BYTES, TRUE);
    if (status == ATOM_OK)
    {
        /* Put a message out on the UART */
        KPrint(logo);

        /* Create an application thread */
        status = atomThreadCreate(&main_tcb,
                     16, main_thread_func, 0,
                     &main_thread_stack[0],
                     ATOM_MAIN_STACK_SIZE_BYTES,
                     TRUE);
        if (status == ATOM_OK)
        {
            /**
             * First application thread successfully created. It is
             * now possible to start the OS. Execution will not return
             * from atomOSStart(), which will restore the context of
             * our application thread and start executing it.
             *
             * Note that interrupts are still disabled at this point.
             * They will be enabled as we restore and execute our first
             * thread in archFirstThreadRestore().
             */
            atomOSStart();
        }
    }
}

void loop() {
  // put your main code here, to run repeatedly:
  atomTimerDelay(SYSTEM_TICKS_PER_SEC);
}

/**
 * \b main_thread_func
 *
 * Entry point for main application thread.
 *
 * This is the first thread that will be executed when the OS is started.
 *
 * @param[in] data Unused (optional thread entry parameter)
 *
 * @return None
 */
static void main_thread_func (uint32_t data)
{
    uint32_t sleep_ticks;

    ConsoleRun();
    init_iap();

    /* Flash LED once per second if passed, very quickly if failed */
    sleep_ticks = SYSTEM_TICKS_PER_SEC;

    /* Test finished, flash slowly for pass, fast for fail */
    while (1)
    {
        /* Sleep then toggle LED again */
        atomTimerDelay (sleep_ticks);
    }
}